package com.zygh.lz.securitys;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zygh.lz.dao.AccountMapper;
import com.zygh.lz.dao.SignboardMapper;
import com.zygh.lz.entity.Account;
import com.zygh.lz.entity.Staff;
import com.zygh.lz.entity.signfile.SignBoard;
import com.zygh.lz.service.AccountService;
import com.zygh.lz.service.StaffService;
import com.zygh.lz.stapprove.SysLogAspect;
import com.zygh.lz.util.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    @Autowired
    JwtUtils jwtUtils;

    @Autowired
    UserDetailServiceImpl userDetailService;

    @Autowired
    StaffService staffService;
    @Resource
    SignboardMapper signboardMapper;
    @Resource
    private AccountService accountService;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        String jwt = request.getHeader(jwtUtils.getHeader());
        if (StrUtil.isBlankOrUndefined(jwt)) {
            chain.doFilter(request, response);
            return;
        }

        Claims claim = jwtUtils.getClaimByToken(jwt);
        if (claim == null) {
            throw new JwtException("token 异常");
        }
        if (jwtUtils.isTokenExpired(claim)) {
            throw new JwtException("token已过期");
        }

        String username = claim.getSubject();
        // 获取用户的权限等信息

       // Staff sysUser = staffService.getByUsername(username);

       Account account = accountService.getByUsername(username);
        UsernamePasswordAuthenticationToken token
                = new UsernamePasswordAuthenticationToken(username, null, userDetailService.getUserAuthority(account.getSysStaffId().longValue()));

        SecurityContextHolder.getContext().setAuthentication(token);


        //==============判断是PC还是APP=====================
        String ua = request.getHeader("User-Agent");
        //APP请求过滤掉
        if (!SysLogAspect.checkAgentIsMobile(ua)) {
            if (username != null) {
                String remoteIP = SysLogAspect.getRemoteIP(request);
                SignBoard signBoard = signboardMapper.selectOne(Wrappers.<SignBoard>lambdaQuery()
                        .eq(SignBoard::getName, username).orderByDesc(SignBoard::getCreateTime)
                        .last("limit 1"));
                // if (signBoard != null && !remoteIP.equals(signBoard.getIp())) {
                //     response.setContentType("application/json;charset=UTF-8");
                //     ServletOutputStream outputStream = response.getOutputStream();
                //     Map<String, Object> map = new HashMap<>();
                //     map.put("code", 403);
                //     map.put("msg", "您被迫下线了");
                //     map.put("data", null);
                //     outputStream.write(JSONUtil.toJsonStr(map).getBytes(StandardCharsets.UTF_8));
                //     outputStream.flush();
                //     outputStream.close();
                // }
            }
        }

        chain.doFilter(request, response);
    }
}
